<?php

namespace Crypt;

class CryptDes {

    /**
     +----------------------------------------------------------
     * 加密字符串
     *
     +----------------------------------------------------------
     * @access static
     +----------------------------------------------------------
     * @param string $str 字符串
     * @param string $key 加密key
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     * @throws ThinkExecption
     +----------------------------------------------------------
     */
    public static function encrypt($str, $key) {
        if ($str == "") {
            return "";
        }
        
        $Block_Size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_ECB);
        $InStr = self::pkcs5Pad($str, $Block_Size);
        $Td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
        $Iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($Td), MCRYPT_RAND);
        mcrypt_generic_init($Td, $key, $Iv);
        $str = mcrypt_generic($Td, $InStr);
        mcrypt_generic_deinit($Td);
        mcrypt_module_close($Td);
        return bin2hex($str);
    }

    /**
     +----------------------------------------------------------
     * 解密字符串
     *
     +----------------------------------------------------------
     * @access static
     +----------------------------------------------------------
     * @param string $str 字符串
     * @param string $key 加密key
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     * @throws ThinkExecption
     +----------------------------------------------------------
     */
    public static function decrypt($str, $key) {
        if ($str == "") {
            return "";
        }
        $StrBin = hex2bin($str);
        $DeStr = mcrypt_decrypt(MCRYPT_DES, $key, $StrBin, MCRYPT_MODE_ECB);
        $ReturnStr = self::pkcs5Unpad($DeStr);
        return $ReturnStr;
    }
    
    private static function pkcs5Pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
 
    private static function pkcs5Unpad($text) {
        $pad = ord($text {strlen($text) - 1});
        if ($pad > strlen($text)) {
            return false;
        }
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
            return false;
        }
        return substr($text, 0, - 1 * $pad);
    }
    
    /**
     * @param type $Data  原数据
     * @param type $PfxPath 私钥路径
     * @param type $Pwd 私钥密码
     */
    public static function sign($Data,$PfxPath,$Pwd){
        if (!function_exists('bin2hex')) {
            return false;
        }
        if(!file_exists($PfxPath)) {
            return false;
        } 
        
        $pkcs12 = file_get_contents($PfxPath);
        $PfxPathStr=array();
        if (openssl_pkcs12_read($pkcs12, $PfxPathStr, $Pwd)) {
            $PrivateKey = $PfxPathStr['pkey'];
            $BinarySignature=NULL;
            if (openssl_sign($Data, $BinarySignature, $PrivateKey, OPENSSL_ALGO_SHA1)) {
                return bin2hex($BinarySignature);
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    
    /**
     * @param string $Data 签名的原文
     * @param string $CerPath  公钥路径
     * @param string $SignaTure 签名
     */
    public static function verifySign($Data,$CerPath,$SignaTure){
        if (!function_exists('hex2bin')) {
            return false;
        }
        if(!file_exists($CerPath)) {
            return false;
        } 
        $PubKey = file_get_contents($CerPath);
        $Certs = openssl_get_publickey($PubKey);
        $ok = openssl_verify($Data,hex2bin($SignaTure), $Certs);
        if ($ok == 1) {
            return true;
        }
        return false;
    }

}